package cn.yunyichina.provider.bone.service.impl;

import cn.yunyichina.provider.bone.dao.ExtensionDao;
import cn.yunyichina.provider.bone.entity.Extension;
import cn.yunyichina.provider.bone.service.BoneService;
import cn.yunyichina.provider.bone.vo.BoneMessageRequestVo;
import cn.yunyichina.provider.framework.annotation.validate.ValidateException;
import cn.yunyichina.provider.framework.annotation.validate.Validator;
import cn.yunyichina.provider.framework.common.PKGenerator;
import cn.yunyichina.provider.framework.dubbo.service.BaseService;
import cn.yunyichina.provider.framework.dubbo.service.MessageService;
import cn.yunyichina.provider.framework.dubbo.service.PayService;
import cn.yunyichina.provider.framework.dubbo.service.WechatPayService;
import cn.yunyichina.provider.framework.exception.CallException;
import cn.yunyichina.provider.framework.page.PageInfo;
import cn.yunyichina.provider.iface.entity.ErrorCodeDefine;
import cn.yunyichina.provider.iface.entity.PersonalUserOpenid;
import cn.yunyichina.provider.iface.entity.base.OrgUserOpenidVo;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.iface.entity.common.ResponseObject;
import cn.yunyichina.provider.iface.entity.message.OrgAppTemplateVo;
import cn.yunyichina.provider.iface.entity.pay.PaymentSettingResponse;
import cn.yunyichina.utils.commons.StringUtils;
import cn.yunyichina.utils.convert.JsonUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by Joe.zhou on 2017/8/23.
 */
@Service
public class BoneServiceImpl implements BoneService{

    private static final Logger logger = LoggerFactory.getLogger(BoneServiceImpl.class);
    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private final static String MESSAGE_LINK_URL="http://www.gloryren.com";
    private final static String DOC_APP_CODE="yytb294d158a26b11e6";

    @Autowired
    private ExtensionDao extensionDao;

    @Resource
    private BoneMsgServiceImpl boneMsgService;


    /**
     * 绑定医生与患者关系
     * @param json
     * @interfaceName: yyt.bone.bone.extension.bind
     * @return
     */
    public Response bindBoneExtension(String data){
        logger.info("BoneServcieImpl.bindBoneExtension(医生和患者绑定关系) json: "+data);
        Response response = new Response();
        Extension extension = JsonUtils.parseObject(data, Extension.class);
        try{
            if("1".equals(extension.getType())){
                Extension extensionUser = new Extension();
                List<Extension> voOpenIdList=null;
                String userId=extension.getPersonalUserId();
                String openId=extension.getPersonalOpenId();
                String userName=extension.getPersonalUserName();
                extensionUser.setPersonalOpenId(openId);
                extensionUser.setPersonalUserId(userId);
                List<Extension> voUserIdList = extensionDao.select(extensionUser);
                Extension extensionOpenId = new Extension();
                extensionOpenId.setPersonalOpenId(openId);
                extensionOpenId.setPersonalUserId(null);
                voOpenIdList = extensionDao.select(extensionOpenId);
                if(voOpenIdList.size() > 0){
                    if(voUserIdList.size() > 0){
                        for (Extension vo : voUserIdList) {
                            for (Extension vo1 : voOpenIdList) {
                                if(!vo.getOrgUserId().equals(vo1.getOrgUserId())){
                                    vo1.setPersonalUserId(userId);
                                    vo1.setPersonalUserName(userName);
                                    vo1.setUpdateTime(simpleDateFormat.format(new Date()));
                                    extensionDao.update(vo1);
                                }
                            }
                        }
                    }else {
                        for (Extension vo1 : voOpenIdList) {
                            vo1.setPersonalUserId(userId);
                            vo1.setPersonalUserName(userName);
                            vo1.setUpdateTime(simpleDateFormat.format(new Date()));
                            extensionDao.update(vo1);
                        }
                    }
                }
            }else if("2".equals(extension.getType())){
                List<Extension> voOrderList = extensionDao.select(extension);
                if(voOrderList.size()<1){
                    extension.setId(PKGenerator.generateId());
                    extension.setPayMode((short) 1);
                    extension.setDefaultFlag((short) 1);
                    extension.setCreatedTime(simpleDateFormat.format(new Date()));
                    extension.setUpdateTime(simpleDateFormat.format(new Date()));
                    extensionDao.insert(extension);
                }
            }else {
                logger.error("BoneServcieImpl.bindBoneExtension(医生和患者绑定关系)->暂不支持改类型type:"+extension.getType() );
                response.setResultCodeAndMessage(Response.FAILURE_CODE , "(医生和患者绑定关系)->暂不支持改类型type");
            }
        } catch (Exception e) {
            logger.error("BoneServcieImpl.bindBoneExtension(医生和患者绑定关系)信息失败" ,e);
            response.setResultCodeAndMessage(Response.FAILURE_CODE , "(医生和患者绑定关系)信息失败");
        }
        return response;
    }

    /**
     * 获取拓展内容患者与医生关系
     * @param json
     * @interfaceName: yyt.bone.bone.extension.get
     * @return
     */
    @Override
    public Response getBoneExtension(String json) {
        logger.info("获取医生与患者绑定关系列表入参BoneServcieImpl.getBoneExtension json: "+json);
        Response response = new Response();
        List<Extension> extensionList=null;
        Map<String, Object> result = new HashMap<>();
        Map<String, String> maps = JsonUtils.parseObject(json, Map.class);
        Extension extension = JsonUtils.parseObject(json, Extension.class);
        String type =extension.getType();
        String perUserId=extension.getPersonalUserId();
        if("1".equals(type)||"2".equals(type)||"3".equals(type)){
            extensionList = extensionDao.select(extension);
            if(extensionList.size() < 1){
                response.setResultCodeAndMessageAndResult(Response.FAILURE_CODE , "查无结果" , null);
            }else {
                response.setResultCodeAndMessageAndResult(Response.SUCCESS_CODE , Response.SUCCESS_MESSAGE , JsonUtils.toJsonString(extensionList));
            }
            return response;
        }else {
            String page_num = maps.get("page_num");
            String page_size = maps.get("page_size");
            if (StringUtils.isBlank(page_num) || StringUtils.isBlank(page_size) || StringUtils.isBlank(perUserId)) {
                response.setResultCodeAndMessage(Response.FAILURE_CODE, "param (page_num or page_size or personal_user_id) is empty");
                return response;
            }
            //查出总记录数
            long count = extensionDao.selectCount(extension);
            logger.info("获取医生与患者绑定关系列表获取数据数量:" + count);

            //根据条件查询医患关系信息，按使用时间倒叙排序
            List<String> orderColumns = new ArrayList<String>();
            orderColumns.add("UPDATE_TIME");

            PageInfo pageInfo = new PageInfo();
            pageInfo.setPageNum(Integer.valueOf(page_num));
            pageInfo.setPageSize(Integer.valueOf(page_size));

            pageInfo.setTotal(count);
            pageInfo.setPages((pageInfo.getTotal().intValue() + pageInfo.getPageSize() - 1) / pageInfo.getPageSize());
            extensionList = extensionDao.select(extension,orderColumns,false,pageInfo);
            logger.info("获取医生与患者绑定关系列表获取数据：" + JSON.toJSONString(extensionList));
            result.put("list", extensionList);
            result.put("page_info", pageInfo);
            response.setResult(JsonUtils.toJsonString(result));
            response.setResultCodeAndMessage("0", "查询成功!");
            return response;
        }
    }



    /**
     * 更新拓展信息
     * @param json
     * @interfaceName: yyt.bone.bone.extension.update
     * @return
     */
    @Override
    public ResponseObject updateBoneExtension(String json) {
        logger.info("BoneServcieImpl.updateBoneExtension json: "+json);
        ResponseObject response = new ResponseObject();
        Extension extension = JsonUtils.parseObject(json, Extension.class);

        try {
            extensionDao.update(extension);
            response.setResultCodeAndMessage(Response.SUCCESS_CODE , Response.FAILURE_MESSAGE);
        } catch (Exception e) {
            logger.error("[BoneServcieImpl.updateBoneExtension] 更新拓展信息失败" ,e);
            response.setResultCodeAndMessage(Response.FAILURE_CODE , "更新拓展信息失败");
        }

        return response;
    }



    /**
     * 新增拓展信息
     * @param json
     * @interfaceName: yyt.bone.bone.extension.add
     * @return
     */
    @Override
    public ResponseObject addBoneExtension(String json) {
        logger.info("BoneServcieImpl.addBoneExtension json: "+json);
        ResponseObject response = new ResponseObject();
        List<Extension> extensionList = JsonUtils.parseArray(json, Extension.class);
        try {
            extensionDao.batchInsert(extensionList);
            response.setResultCodeAndMessage(Response.SUCCESS_CODE , Response.FAILURE_MESSAGE);
        } catch (Exception e) {
            logger.error("[BoneServcieImpl.addBoneExtension] 新增拓展信息失败" ,e);
            response.setResultCodeAndMessage(Response.FAILURE_CODE , "新增拓展信息失败");
        }

        return response;
    }



    /**
     * 后台主动发起推送消息
     * @param json
     * @interfaceName: yyt.bone.bone.message.send
     * @return
     */
    public ResponseObject sendBoneMessage(String json) {
        logger.info("后台主动发起推送消息->BoneServcieImpl.sendBoneMessage json: " + json);
        ResponseObject response = new ResponseObject();
        Set<String> set = new HashSet<String>();
        String perOpenId = null;
        BoneMessageRequestVo request = JsonUtils.parseObject(json, BoneMessageRequestVo.class);

        try {
            Validator.getInstance().validate(request);
        } catch (ValidateException ex) {
            logger.info("sendBoneMessage 数据校验失败:" + ex.getMessage() + "|入参:" + json + "！");
            response.setResultCodeAndMessage("13", "数据校验失败:" + ex.getMessage() + "！");
            return response;
        }

        Map<String, String> param = JsonUtils.parseObject(json, Map.class);

        ResCommon<PaymentSettingResponse> settingResponseResCommon = PayService.getPayClient().queryPaymentSettingByAppId(request.getAppId());
        PaymentSettingResponse settingResponse = settingResponseResCommon.getResult();
        String secretKey = settingResponse.getSecretKey();

        //根据订单好查出订单对象
        Map<String, String> ordQueryMap = new HashMap<String, String>();
        ordQueryMap.put("order_no", request.getOrderNo());
        Response ordResponse = cn.yunyichina.provider.framework.dubbo.service.BoneService.callUnderlineFromInternal("yyt.bone.order.get", JsonUtils.toJsonString(ordQueryMap));
        logger.info("sendBoneMsg, yyt.bone.order.get ordResponse=" + JSON.toJSONString(ordResponse));
        if (!"0".equals(ordResponse.getResultCode())) {
            response.setResultCodeAndMessage("1001", "查询订单失败。");
            return response;
        }
        JSONObject order = JSONObject.parseObject(ordResponse.getResult());
        if ("3".equals(request.getType())) {//后台点击发送给专家
            OrgUserOpenidVo openidVo = new OrgUserOpenidVo();
            openidVo.setOrgUserId(request.getUserId());
            openidVo.setAppCode(DOC_APP_CODE);
            logger.info("后台主动发起推送消息->用户和医生系统帐号和公众号/服务窗对应关系sendBoneMessage->request:" + JSON.toJSONString(openidVo));
            Response responseOrgUser = BaseService.callUnderlineFromInternal("yyt.base.orgopenid.get", JsonUtils.toJsonString(openidVo));
            logger.info("后台主动发起推送消息->用户和医生系统帐号和公众号/服务窗对应关系sendBoneMessage->response->" + JSON.toJSONString(responseOrgUser));
            if ("0".equals(responseOrgUser.getResultCode())) {
                List<OrgUserOpenidVo> orgUserOpenidVos = JsonUtils.parseArray(responseOrgUser.getResult(), OrgUserOpenidVo.class);
                openidVo = orgUserOpenidVos.get(0);
            }
            param.put("to_user", openidVo.getOpenId());
            perOpenId = order.getString("open_id");
        } else if ("4".equals(request.getType())) {//后台点击发送给患者
            logger.debug("后台主动发起推送消息->医生和用户帐号和公众号/服务窗对应关系sendBoneMessage->request:userId=" + request.getUserId() + ",appId=" + request.getAppId());
            PersonalUserOpenid personalUserOpenid = BaseService.getBaseClient().getPersonalUserOpenid(request.getUserId(), request.getAppId(),null);
            logger.debug("后台主动发起推送消息->医生和用户帐号和公众号/服务窗对应关系sendBoneMessage->response:" + JsonUtils.toJsonString(personalUserOpenid));
            if (personalUserOpenid == null) {
                throw new CallException(ErrorCodeDefine.MESSAGE_NOT_FIND_OPENID, "找不到应用账号");
            }
            param.put("to_user", personalUserOpenid.getOpenId());
            perOpenId = personalUserOpenid.getOpenId();
        } else {
            param.put("to_user", request.getSendOpenId());
            perOpenId = request.getSendOpenId();
        }
        //获取模板id
        OrgAppTemplateVo templateVo = new OrgAppTemplateVo();
        templateVo.setPlatformOrgAppCode(request.getSendAppCode());
        templateVo.setPlatformTemplateCode(request.getTemplateCode());
        templateVo.setLibraryTemplateCode("TMP".concat(request.getTemplateCode()));
        Response mesReps = MessageService.callHumpFromInternal("yyt.message.msg.app.template.get", JsonUtils.toJsonString(templateVo));
        logger.info("后台主动发起推送消息->根据orgAppCode:{}、templateCode:{}、LibraryTemplateCode:{},请求返回对应消息模板" +
                ":{}", request.getSendAppCode(), request.getTemplateCode(), "TMP".concat(request.getTemplateCode()), JSON.toJSONString(mesReps));
        if (!"0".equals(mesReps.getResultCode())) {
            response.setResultCodeAndMessage(Response.FAILURE_CODE, mesReps.getResultMessage());
            return response;
        } else {
            List<OrgAppTemplateVo> orgAppTemplateVos = JsonUtils.parseArray(mesReps.getResult(), OrgAppTemplateVo.class);
            templateVo = orgAppTemplateVos.get(0);
        }

        param.put("template_id", templateVo.getPayTemplateId());

        String userName = order.getString("user_name");
        String orderTime = order.getString("update_time");

        String orderTypeName = "";
        String orderType = ""; // 1:问诊单   2：手术单
        if (order.getString("order_type") != null && order.getString("order_type").equals("91")) {
            orderTypeName = "问诊";
            orderType = "1";
        } else if (order.getString("order_type") != null && (order.getString("order_type").equals("93") || order.getString("order_type").equals("92"))) {
            orderTypeName = "手术预约";
            orderType = "2";
        }

        String appointmentDoctorName = order.getString("appointment_doctor_name");
        String professorDoctorName = order.getString("professor_doctor_name");
        if (!StringUtils.isEmpty(appointmentDoctorName)) {
            set.add(order.getString("appointment_doctor_id"));
        }
        if (!StringUtils.isEmpty(professorDoctorName)) {
            set.add(order.getString("professor_doctor_id"));
        }
        String actionUrl = null;
        param.put("payment_setting", "{\"secret_key\":\"" + secretKey + "\",\"pay_app_id\":\"" + request.getAppId() + "\"}");
        if ("36010".equals(request.getTemplateCode())) {//专家反馈通知，发送给患者
            if ("1".equals(orderType)) {// 1:问诊单   2：手术单
                actionUrl = MESSAGE_LINK_URL + "/orthopedicPlatform/dist/#/user/consultation/step3?orderNo=" + request.getOrderNo() + "&appCode=" + request.getSendAppCode();
            } else {
                actionUrl = MESSAGE_LINK_URL + "/orthopedicPlatform/dist/#/user/reservation/step3?orderNo=" + request.getOrderNo() + "&appCode=" + request.getSendAppCode();
            }
            param.put("msg_content", "{\"remark\":{\"node\":\"remark\",\"value\":\"温馨提示：若有相关疑问，可联系客服电话020-85600747。\",\"font_color\":\"black\"}," +
                    "\"keyword5\":{\"node\":\"keyword5\",\"value\":\"" + orderTypeName + "\",\"font_color\":\"black\"}," +
                    "\"keyword1\":{\"node\":\"keyword1\",\"value\":\"" + userName + "\",\"font_color\":\"black\"}," +
                    "\"keyword2\":{\"node\":\"keyword2\",\"value\":\"" + appointmentDoctorName + "\",\"font_color\":\"black\"}," +
                    "\"first\":{\"node\":\"first\",\"value\":\"您好，" + userName + "，您提交的" + orderTypeName + "订单专家已反馈，请查看。请尽快处理相关事宜。\",\"font_color\":\"black\"}," +
                    "\"keyword3\":{\"node\":\"keyword3\",\"value\":\"" + request.getOrderNo() + "\",\"font_color\":\"black\"}," +
                    "\"keyword4\":{\"node\":\"keyword4\",\"value\":\"" + orderTime + "\",\"font_color\":\"black\"}}");
        } else if ("36004".equals(request.getTemplateCode())) {//发送专家处理订单
            actionUrl = MESSAGE_LINK_URL + "/orthopedicPlatform/dist/#/expert/orderManage/surgeryOrder?orderNo=" + request.getOrderNo() + "&app_code=" + request.getSendAppCode() + "";
            param.put("msg_content", "{\"remark\":{\"node\":\"remark\",\"value\":\"温馨提示：若有相关疑问，可联系客服电话020-85600747。\",\"font_color\":\"black\"}," +
                    "\"keyword5\":{\"node\":\"keyword5\",\"value\":\"" + orderTypeName + "\",\"font_color\":\"black\"}," +
                    "\"keyword1\":{\"node\":\"keyword1\",\"value\":\"" + userName + "\",\"font_color\":\"black\"}," +
                    "\"keyword2\":{\"node\":\"keyword2\",\"value\":\"" + professorDoctorName + "\",\"font_color\":\"black\"}," +
                    "\"first\":{\"node\":\"first\",\"value\":\"您好，" + appointmentDoctorName + "医生，有一笔" + orderTypeName + "订单需要您进行处理，请在1个工作日内尽快处理，谢谢！\",\"font_color\":\"black\"}," +
                    "\"keyword3\":{\"node\":\"keyword3\",\"value\":\"" + request.getOrderNo() + "\",\"font_color\":\"black\"}," +
                    "\"keyword4\":{\"node\":\"keyword4\",\"value\":\"" + orderTime + "\",\"font_color\":\"black\"}}");
        } else if ("36005".equals(request.getTemplateCode())) {//发送主治医生
            if ("1".equals(request.getType())) {//主治医生
                actionUrl = MESSAGE_LINK_URL + "/orthopedicPlatform/dist/#/doctor/recommendRecord/surgeryOrder?orderNo=" + request.getOrderNo();
            } else if ("2".equals(request.getType())) {//专家
                actionUrl = MESSAGE_LINK_URL + "/orthopedicPlatform/dist/#/expert/recommendRecord/surgeryOrder?orderNo=" + request.getOrderNo();
            }
            //暂时保留，患者通过主治医生推荐消息推送
            /*param.put("msg_content" , "{\"remark\":{\"node\":\"remark\",\"value\":\"温馨提示：若有相关疑问，可联系客服电话020-85600747。\",\"font_color\":\"black\"}," +
                    "\"keyword5\":{\"node\":\"keyword5\",\"value\":\""+ orderTypeName +"\",\"font_color\":\"black\"}," +
                    "\"keyword1\":{\"node\":\"keyword1\",\"value\":\""+ userName +"\",\"font_color\":\"black\"}," +
                    "\"keyword2\":{\"node\":\"keyword2\",\"value\":\""+ appointmentDoctorName +"\",\"font_color\":\"black\"}," +
                    "\"first\":{\"node\":\"first\",\"value\":\"您好，"+ professorDoctorName +"医生，有一笔手术预约订单需要您提交患者的病情资料，请在1个工作日内尽快处理，谢谢！\",\"font_color\":\"black\"}," +
                    "\"keyword3\":{\"node\":\"keyword3\",\"value\":\""+ request.getOrderNo() +"\",\"font_color\":\"black\"}," +
                    "\"keyword4\":{\"node\":\"keyword4\",\"value\":\""+ orderTime +"\",\"font_color\":\"black\"}}");*/
            //主治医生帮患者预约专家
            param.put("msg_content", "{\"remark\":{\"node\":\"remark\",\"value\":\"温馨提示：若有相关疑问，可联系客服电话020-85600747。\",\"font_color\":\"black\"}," +
                    "\"keyword5\":{\"node\":\"keyword5\",\"value\":\"" + orderTypeName + "\",\"font_color\":\"black\"}," +
                    "\"keyword1\":{\"node\":\"keyword1\",\"value\":\"" + userName + "\",\"font_color\":\"black\"}," +
                    "\"keyword2\":{\"node\":\"keyword2\",\"value\":\"" + appointmentDoctorName + "\",\"font_color\":\"black\"}," +
                    "\"first\":{\"node\":\"first\",\"value\":\"您好，" + professorDoctorName + "医生，您已推荐患者进行" + orderTypeName + "，请将生成的二维码推荐给患者扫描并让患者及时支付，谢谢！\",\"font_color\":\"black\"}," +
                    "\"keyword3\":{\"node\":\"keyword3\",\"value\":\"" + request.getOrderNo() + "\",\"font_color\":\"black\"}," +
                    "\"keyword4\":{\"node\":\"keyword4\",\"value\":\"" + orderTime + "\",\"font_color\":\"black\"}}");
        } else {
            logger.info("无法匹配消息模板，请检查传入TemplateCode是否正确:" + request.getTemplateCode());
        }
        param.put("url", actionUrl);
        logger.info("主动发起推送消息请求入参:" + JSON.toJSONString(param));
        Response weReps = WechatPayService.callHumpFromInternal("yyt.wechatpay.wechat.message.template.send", JSON.toJSONString(param));
        logger.info("主动发起推送消息请求出参:" + JSON.toJSONString(weReps));
        if (!CollectionUtils.isEmpty(set)) {
            Iterator<String> it = set.iterator();
            while (it.hasNext()) {
                Extension extension = new Extension();
                String str = it.next();
                extension.setOrgUserId(str);
                extension.setPersonalUserId(order.getString("user_id"));
                List<Extension> voOrderList = extensionDao.select(extension);
                if (voOrderList.size() < 1) {
                    extension.setId(PKGenerator.generateId());
                    extension.setPersonalOpenId(perOpenId);
                    extension.setPayMode((short) 1);
                    extension.setDefaultFlag((short) 1);
                    extension.setCreatedTime(simpleDateFormat.format(new Date()));
                    extension.setUpdateTime(simpleDateFormat.format(new Date()));
                    extensionDao.insert(extension);
                }
            }
        }
        if ("0".equals(weReps.getResultCode())) {
            response.setResultCodeAndMessage(weReps.getResultCode(), weReps.getResultMessage());
        } else {
            logger.info("后台主动发起推送消息 resultCode:" + weReps.getResult() + "--- message:" + weReps.getResultMessage());
            response.setResultCodeAndMessage(weReps.getResultCode(), weReps.getResultMessage());
        }

        return response;
    }


    /*方法跳板*/
        public ResponseObject sendBoneMsgSuccessOrder (String data){
            return boneMsgService.sendBoneMsgSuccessOrder(data);
        }

        public ResponseObject sendBoneMsgSurgeryArrangeOrder (String data){
            return boneMsgService.sendBoneMsgSurgeryArrangeOrder(data);
        }

        public ResponseObject sendBoneMsgCancelOrder (String data){
            return boneMsgService.sendBoneMsgCancelOrder(data);
        }

}
